package com.example.JavaWebApi.core.neo4j;

import com.example.JavaWebApi.core.excelhelper.annotation.HeaderMapper;
import com.example.JavaWebApi.core.excelhelper.annotation.OperationType;
import com.example.JavaWebApi.core.mybatisplusextention.wrapperCreator.ConnectorType;
import com.example.JavaWebApi.core.mybatisplusextention.wrapperCreator.OperatorType;
import lombok.Data;
import lombok.SneakyThrows;
import org.jsoup.internal.StringUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @program: lvzhengcao_api
 * @description:
 * @author: 杨泽
 * @create: 2023-11-15 15:16
 */
@Data
public class Neo4jQueryWrapper extends Neo4jAbstractQueryWrapper {
    protected List<Neo4jQueryWrapper> andWrapperList=new ArrayList<>();
    protected List<Neo4jQueryWrapper> orWrapperList=new ArrayList<>();
    protected List<Neo4jCollectionQueryWrapper> funcWrapperList=new ArrayList<>();

    public Neo4jQueryWrapper addCondition(Boolean condition, ConnectorType connectorType, OperatorType operatorType, String column , Object value){
        if(condition){
            super.createCondition(column,value,connectorType,operatorType);
        }
        return this;
    }
    public Neo4jQueryWrapper addCondition(ConnectorType connectorType, OperatorType operatorType, String column , Object value){
        return addCondition(true,connectorType,operatorType,column,value);
    }

    /**
     * Description: 等于
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jTestQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:25
     */
    public Neo4jQueryWrapper eq(boolean condition, String column, Object value){
        super.baseEq(condition,column,value);
        return this;
    }
    /**
     * Description: 等于
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:25
     */
    public Neo4jQueryWrapper eq(String column, Object value){
        super.baseEq(true,column,value);
        return this;
    }
    /**
     * Description: 不等于
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:26
     */
    public Neo4jQueryWrapper ne(boolean condition, String column, Object value){
        super.baseNe(condition,column,value);
        return this;
    }
    /**
     * Description: 不等于
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:26
     */
    public Neo4jQueryWrapper ne(String column, Object value){
        return this.ne(true,column,value);
    }
    /**
     * Description: 大于
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:26
     */
    public Neo4jQueryWrapper gt(boolean condition, String column, Object value){
        super.baseGt(condition,column,value);
        return this;
    }

    /**
     * Description: 大于
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:26
     */
    public Neo4jQueryWrapper gt(String column, Object value){
        return this.gt(true,column,value);
    }
    /**
     * Description: 大于等于
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper ge(boolean condition, String column, Object value){
        super.baseGe(condition,column,value);
        return this;
    }

    /**
     * Description: 大于等于
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper ge(String column, Object value){
        this.ge(true,column,value);
        return this;
    }
    /**
     * Description: 小于
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper lt(boolean condition, String column, Object value){
        super.baseLt(condition,column,value);
        return this;
    }
    /**
     * Description: 小于
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper lt(String column, Object value){
        return this.lt(true,column,value);
    }
    /**
     * Description: 小于等于
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper le(boolean condition, String column, Object value){
        super.baseLe(condition,column,value);
        return this;
    }
    /**
     * Description: 小于等于
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper le(String column, Object value){
        return this.le(true,column,value);
    }
    /**
     * Description: 模糊查询
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper like(boolean condition, String column, Object value){
        super.baseLike(condition,column,value);
        return this;
    }

    /**
     * Description: 模糊查询
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:27
     */
    public Neo4jQueryWrapper like(String column, Object value){
        return this.like(true,column,value);
    }
    /**
     * Description: 右模糊
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper likeRight(boolean condition, String column, Object value){
        super.baseLikeRight(condition,column,value);
        return this;
    }
    /**
     * Description: 右模糊
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper likeRight(String column, Object value){
        return likeRight(true,column,value);
    }
    /**
     * Description: 左模糊
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper likeLeft(boolean condition, String column, Object value){
        super.baseLikeLeft(condition,column,value);
        return this;
    }
    /**
     * Description: 左模糊
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper likeLeft(String column, Object value){
        return this.likeLeft(true,column,value);
    }
    /**
     * Description:模糊取反
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper notLike(boolean condition, String column, Object value){
        super.baseNotLike(condition,column,value);
        return this;
    }
    /**
     * Description:模糊取反
     * @param column 查询字段
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper notLike(String column, Object value){
        return this.notLike(true,column,value);
    }
    /**
     * Description: 包含
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param coll 集合
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper in(boolean condition, String column, Collection<?> coll){
        super.baseIn(condition,column,coll);
        return this;
    }
    /**
     * Description: 包含
     * @param column 查询字段
     * @param coll 集合
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:28
     */
    public Neo4jQueryWrapper in(String column, Collection<?> coll){
        return this.in(true,column,coll);
    }

    public Neo4jQueryWrapper in(Boolean condition,String column,Object...values){
        List<?> list= Arrays.asList(values);
        return this.in(condition,column,list);
    }
    public Neo4jQueryWrapper in(String column,Object...values){
        return in(true,column,values);
    }
    /**
     * Description: 不包含
     * @param condition 为true拼接条件 false不拼接
     * @param column 查询字段
     * @param coll 集合
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:29
     */
    public Neo4jQueryWrapper notIn(boolean condition, String column, Collection<?> coll){
        super.baseNotIn(condition,column,coll);
        return this;
    }
    /**
     * Description: 不包含
     * @param column 查询字段
     * @param coll 集合
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:29
     */
    public Neo4jQueryWrapper notIn(String column, Collection<?> coll){
        return this.notIn(true,column,coll);
    }
    /**
     * Description: 标签查询
     * @param condition 为true拼接条件 false不拼接
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:53
     */
    public Neo4jQueryWrapper label(Boolean condition, String parameterName, Object value){
        super.baseLabel(condition,parameterName,value);
        return this;
    }
    /**
     * Description: 标签查询
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:54
     */
    public Neo4jQueryWrapper label(String parameterName, Object value){
        return this.label(true,parameterName,value);
    }
    /**
     * Description: 非标签查询
     * @param condition 为true拼接条件 false不拼接
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:53
     */
    public Neo4jQueryWrapper notLabel(Boolean condition, String parameterName, Object value){
        super.baseNotLabel(condition,parameterName,value);
        return this;
    }
    /**
     * Description: 非标签查询
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:54
     */
    public Neo4jQueryWrapper notLabel(String parameterName, Object value){
        return notLabel(true,parameterName,value);
    }
    /**
     * Description: 关系类型
     * @param condition 为true拼接条件 false不拼接
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper type(Boolean condition, String parameterName, Object value){
        super.baseType(condition,parameterName,value);
        return this;
    }
    /**
     * Description: 关系类型
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper type(String parameterName, Object value){
        return type(true,parameterName,value);
    }
    /**
     * Description: 非关系类型
     * @param condition 为true拼接条件 false不拼接
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper notType(Boolean condition, String parameterName, Object value){
        super.baseNotType(condition,parameterName,value);
        return this;
    }
    /**
     * Description: 非关系类型
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper notType(String parameterName, Object value){
        return notType(true,parameterName,value);
    }

    /**
     * Description: 主键id
     * @param condition 为true拼接条件 false不拼接
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper id(Boolean condition, String parameterName, Object value){
        super.baseId(condition,parameterName,value);
        return this;
    }
    /**
     * Description: 主键id
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper id(String parameterName, Object value){
        return id(true,parameterName,value);
    }
    /**
     * Description: 非主键id
     * @param condition 为true拼接条件 false不拼接
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper notId(Boolean condition, String parameterName, Object value){
        super.baseNotId(condition, parameterName, value);
        return this;
    }
    /**
     * Description: 非主键id
     * @param parameterName 参数名
     * @param value 值
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2024/4/24 上午10:56
     */
    public Neo4jQueryWrapper notId(String parameterName, Object value){
        return notId(true,parameterName,value);
    }

    /**
     * Description: 直接拼接语句
     * @param condition 为true拼接条件 false不拼接
     * @param sql 拼接语句
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:30
     */
    public Neo4jQueryWrapper applySql(boolean condition, String sql){
        baseApplySql(condition,sql);
        return this;
    }

    /**
     * Description: 直接拼接语句
     * @param sql 拼接语句
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:30
     */
    public Neo4jQueryWrapper applySql(String sql){
        return this.applySql(true,sql);
    }
    /**
     * Description: 将map转为objCQL
     * @param parameterName CQL语句中的占位符
	 * @param map 对象map
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/12/14 14:35
     */
    public Neo4jQueryWrapper object2CQL(String parameterName, Map<String,Object> map){
        super.baseObject2CQL(parameterName,map);
        return this;
    }

    /**
     * Description: 将map指定的key转换为对象
     * @param parameterName CQL占位符参数名
     * @param map 对象map
     * @param keys 指定生成对象的key
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/12/8 16:21
     */
    public Neo4jQueryWrapper object2CQLIncludeKeys(String parameterName,Map<String,Object> map,String...keys){
        Map<String,Object> newMap=new HashMap<>();
        for(String key :keys){
            newMap.put(key,map.get(key));
        }
        return object2CQL(parameterName,newMap);
    }
    /**
     * Description: 将map中除了指定key以外的值转成对象
     * @param parameterName 占位符参数名
     * @param map 对象map
     * @param keys 指定不生成对象的key
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/12/8 16:21
     */
    public Neo4jQueryWrapper object2CQLExcludeKeys(String parameterName,Map<String,Object> map,String...keys){
        Map<String,Object> newMap=new HashMap<>();
        for(Map.Entry<String,Object> entry:map.entrySet()){
            List<String> keyList=Arrays.asList(keys);
            if(!keyList.contains(entry.getKey())){
                newMap.put(entry.getKey(),entry.getValue());
            }
        }
        return object2CQL(parameterName,newMap);
    }
    public Neo4jQueryWrapper object2CQL(String parameterName,Object object){
        Map<String,Object> map=object2Map(object);
        return this.object2CQL(parameterName,map);
    }


    @SneakyThrows
    private Map<String,Object> object2Map(Object obj){
        Class<?> clazz=obj.getClass();
        Map<String, Object> map=new HashMap<>();
        List<Field> fields= Arrays.stream(clazz.getDeclaredFields()).collect(Collectors.toList());
        Class superClass=clazz.getSuperclass();
        while (!superClass.equals(Object.class)){
            List<Field> superField= Arrays.stream(superClass.getDeclaredFields()).collect(Collectors.toList());
            fields.addAll(superField);
            superClass=superClass.getSuperclass();
        }
        for (Field field:fields){
            int mod=field.getModifiers();
            if(!Modifier.isStatic(mod)){
                field.setAccessible(true);
                Object value=field.get(obj);
                if(value!=null){
                    map.put(field.getName(),value);
                }
            }
        }
        return map;
    }
    public Neo4jQueryWrapper addCollectionFunction(Boolean condition,ConnectorType connectorType, FuncType funcType,String collectionColumn,Consumer<Neo4jCollectionQueryWrapper> neo4jCollectionQueryWrapperConsumer){
        if(condition){
            Neo4jCollectionQueryWrapper queryWrapper=new Neo4jCollectionQueryWrapper(collectionColumn,connectorType,funcType);
            neo4jCollectionQueryWrapperConsumer.accept(queryWrapper);
            funcWrapperList.add(queryWrapper);
        }
        return this;
    }
    public Neo4jQueryWrapper addCollectionFunction(ConnectorType connectorType,FuncType funcType,String collectionColumn, Consumer<Neo4jCollectionQueryWrapper> neo4jCollectionQueryWrapperConsumer){
        return addCollectionFunction(true,connectorType,funcType,collectionColumn,neo4jCollectionQueryWrapperConsumer);
    }

    /**
     * Description: 使用and连接符继续拼接一个条件
     * @param condition 为true拼接条件 false不拼接
     * @param queryWrapperConsumer
     * @return com.example.JavaWebApi.core.neo4j.Neo4jAbstractQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:30
     */
    public Neo4jQueryWrapper and(boolean condition, Consumer<Neo4jQueryWrapper> queryWrapperConsumer){
        if(condition){
            Neo4jQueryWrapper queryWrapper=new Neo4jQueryWrapper();
            queryWrapperConsumer.accept(queryWrapper);
            andWrapperList.add(queryWrapper);
        }
        return this;
    }
    /**
     * Description: 使用and连接符继续拼接一个条件
     * @param queryWrapperConsumer
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:30
     */
    public Neo4jQueryWrapper and(Consumer<Neo4jQueryWrapper> queryWrapperConsumer){
        return this.and(true,queryWrapperConsumer);
    }
    /**
     * Description: 使用or连接符继续拼接一个条件
     * @param condition 为true拼接条件 false不拼接
     * @param queryWrapperConsumer
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:30
     */
    public Neo4jQueryWrapper or(boolean condition, Consumer<Neo4jQueryWrapper> queryWrapperConsumer){
        if(condition){
            Neo4jQueryWrapper queryWrapper=new Neo4jQueryWrapper();
            queryWrapperConsumer.accept(queryWrapper);
            orWrapperList.add(queryWrapper);
        }
        return this;
    }
    /**
     * Description: 使用or连接符继续拼接一个条件
     * @param queryWrapperConsumer
     * @return com.example.JavaWebApi.core.neo4j.Neo4jQueryWrapper
     * @author 杨泽
     * @date 2023/11/2 11:30
     */
    public Neo4jQueryWrapper or(Consumer<Neo4jQueryWrapper> queryWrapperConsumer){
        return this.or(true,queryWrapperConsumer);
    }

    public Neo4jQueryWrapper orderByAsc(Boolean condition,String column){
        super.baseOrderByAsc(condition,column);
        return this;
    }
    public Neo4jQueryWrapper orderByAsc(String column){
        return orderByAsc(true,column);
    }
    public Neo4jQueryWrapper orderByDesc(Boolean condition,String column){
        super.baseOrderByDesc(condition,column);
        return this;
    }
    public Neo4jQueryWrapper orderByDesc(String column){
        return orderByDesc(true,column);
    }
    @Override
    public String build(Integer wrapperIndex){
        super.build(wrapperIndex);
        StringBuilder stringBuilder=new StringBuilder(finalConditionCql);
        if(andWrapperList.size()>0){
            stringBuilder.append(" and (");
            for (Neo4jQueryWrapper andWrapper : andWrapperList){
                wrapperIndex++;
                stringBuilder.append(andWrapper.build(wrapperIndex));
            }
            stringBuilder.append(")");
        }
        if(orWrapperList.size()>0){
            stringBuilder.append(" or (");
            for (Neo4jQueryWrapper orWrapper : orWrapperList){
                wrapperIndex++;
                stringBuilder.append(orWrapper.build(wrapperIndex));
            }
            stringBuilder.append(")");
        }
        if(funcWrapperList.size()>0){
            for (Neo4jCollectionQueryWrapper allWrapper : funcWrapperList){
                wrapperIndex++;
                stringBuilder.append(allWrapper.build(wrapperIndex));
            }
        }
        mergeParameter(andWrapperList);
        mergeParameter(orWrapperList);
        mergeParameter(funcWrapperList);
        stringBuilder.append(" ");
        finalConditionCql=stringBuilder.toString();
        return finalConditionCql;
    }

}
